/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package test2.shashindra;

import com.googlecode.javacpp.Loader;
import java.awt.Color;
import java.awt.Graphics;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;


import com.googlecode.javacv.FrameGrabber.Exception;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import com.googlecode.javacv.*;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import java.awt.event.KeyEvent;

public class CalculatePoint implements Runnable {

    CanvasFrame canvas = new CanvasFrame("Web Cam Live");
    CanvasFrame canvas1 = new CanvasFrame("HSV Skin");
    CanvasFrame path = new CanvasFrame("Position");
    JPanel jp = new JPanel();

    {
        path.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
        path.setContentPane(jp);
        path.setSize(800, 600);
    }
    //   CanvasFrame canvas2 = new CanvasFrame("YCrCb Skin");
    CanvasFrame canvas3 = new CanvasFrame("Contours");
    CvScalar rgba_min = cvScalar(124, 133, 18, 0);
    CvScalar rgba_max = cvScalar(184, 193, 80, 0);
    CvScalar hsv_min = cvScalar(0, 45, 0, 0);
    CvScalar hsv_max = cvScalar(20, 255, 255, 0);
    CvScalar ycc_min = cvScalar(0, 131, 80, 0);
    CvScalar ycc_max = cvScalar(255, 185, 135, 0);
    //AdaptiveSkinDetector2 adapSkin=new AdaptiveSkinDetector(1,2):
    CvMemStorage storage = CvMemStorage.create();
    CvMemStorage storage1 = CvMemStorage.create();
    CvSeq hull;
    CvSeq fileredHull;
    CvSeq defects;
    IplImage image;

    public CalculatePoint() {

        canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

    }

    public void run() {
        //FrameGrabber grabber = new OpenCVFrameGrabber("resources/fypVid1.avi");
        FrameGrabber grabber = new VideoInputFrameGrabber(2);
        CvPoint[] src = new CvPoint[3];
        CvPoint[] dst = new CvPoint[3];

        CvPoint2D32f srcPnts = new CvPoint2D32f(3);
        CvPoint2D32f dstPnts = new CvPoint2D32f(3);

        CvMat affineMat = cvCreateMat(2, 3, CV_32FC1);
        dst[0] = new CvPoint(100, 100);
        dst[1] = new CvPoint(100, 500);
        dst[2] = new CvPoint(700, 100);

        dstPnts.position(0).put(0,0);
        dstPnts.position(0).put(0,600);
        dstPnts.position(0).put(800,0);

        try {

            grabber.start();
            Thread.sleep(1000);
            IplImage img;
            Graphics g = jp.getGraphics();

            g.setColor(Color.RED);
            g.fillOval(100, 100, 10, 10);

            g = jp.getGraphics();
            g.setColor(Color.RED);
            g.fillOval(700, 100, 10, 10);

            g = jp.getGraphics();
            g.setColor(Color.RED);
            g.fillOval(100, 500, 10, 10);

            g = jp.getGraphics();
            g.setColor(Color.RED);
            g.fillOval(700, 500, 10, 10);
            KeyEvent ke;
            int[] point;
//            for (int h = 0; h < 3; h++) {
//                ke = canvas.waitKey(0);
//                img = grabber.grab();
//                if (img != null) {
//                    //canvas.showImage(img);
//                    IplImage hsvSkin = getHSVSkin(img);
//                    //canvas1.showImage(hsvSkin);
//                    point=extractContours(hsvSkin, img);
//                    src[h]=new CvPoint(point[0],point[1]);
//                    srcPnts.position(h).put(point[0],point[1]);
//                    System.out.println("Got "+h+" coordinate");
//                    //canvas3.showImage(img);
//                } else {
//                    h--;
//                }
//            }

            srcPnts.position(1).put(0,0);
            srcPnts.position(1).put(0,600);
            srcPnts.position(1).put(800,0);

            affineMat=cvGetAffineTransform(srcPnts, dstPnts, affineMat);
            CvScalar ty=new CvScalar(0);
            while (true) {
                img = grabber.grab();
                image=cvCreateImage(img.cvSize(),img.depth() , img.nChannels());
                if (img != null) {
                    //canvas.showImage(img);
                    cvWarpAffine(img, image, affineMat,CV_WARP_INVERSE_MAP,ty);

                    cvUndistort2(img, image, affineMat, affineMat);
                     //cvUndistort2(img, image, affineMat);
                   //// cvTransform(img, image, affineMat, null);
                    //cvWar
                    canvas.showImage(image);
                    canvas1.showImage(img);
                    IplImage hsvSkin = getHSVSkin(img);
                    //canvas1.showImage(hsvSkin);
                    extractContours(hsvSkin, img);
                    canvas3.showImage(img);
                }
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(CalculatePoint.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception e) {
            try {
                grabber.stop();
            } catch (Exception ex) {
                Logger.getLogger(CalculatePoint.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    private IplImage getThresholdImage(IplImage orgImg) {
        IplImage imgThreshold = cvCreateImage(cvGetSize(orgImg), 8, 1);
        cvInRangeS(orgImg, rgba_min, rgba_max, imgThreshold);
        cvSmooth(imgThreshold, imgThreshold, CV_MEDIAN, 15);
        return imgThreshold;


    }

    private IplImage getHSVSkin(IplImage orgImg) {
        IplImage imgHSV = cvCreateImage(cvGetSize(orgImg), 8, 3);
        IplImage imgThreshold = cvCreateImage(cvGetSize(orgImg), 8, 1);

        cvCvtColor(orgImg, imgHSV, CV_BGR2HSV);
        cvInRangeS(imgHSV, hsv_min, hsv_max, imgThreshold);

        IplConvKernel rect_12 = cvCreateStructuringElementEx(3, 3, 2, 2, CV_SHAPE_ELLIPSE, null);
        // cvErode(imgThreshold, imgThreshold, rect_12, 1);
        IplConvKernel rect_6 = cvCreateStructuringElementEx(7, 7, 2, 2, CV_SHAPE_ELLIPSE, null);
        cvMorphologyEx(imgThreshold, imgThreshold, image, rect_12, CV_MOP_CLOSE, 1);
        cvMorphologyEx(imgThreshold, imgThreshold, image, rect_6, CV_MOP_OPEN, 1);


//        cvDilate(imgThreshold, imgThreshold, rect_6, 1);

        cvSmooth(imgThreshold, imgThreshold, CV_MEDIAN, 5);

        return imgThreshold;


    }

    private IplImage getYCrCbSkin(IplImage orgImg) {
        IplImage imgYCC = cvCreateImage(cvGetSize(orgImg), 8, 3);
        IplImage imgThreshold = cvCreateImage(cvGetSize(orgImg), 8, 1);

        cvCvtColor(orgImg, imgYCC, CV_BGR2YCrCb);
        cvInRangeS(imgYCC, ycc_min, ycc_max, imgThreshold);
        //cvDilate(imgThreshold, imgThreshold, null, 1);
        //cvErode(imgThreshold, imgThreshold, null, 1);

        IplConvKernel rect_12 = cvCreateStructuringElementEx(6, 6, 2, 2, CV_SHAPE_RECT, null);
        cvErode(imgThreshold, imgThreshold, rect_12, 1);

        IplConvKernel rect_6 = cvCreateStructuringElementEx(6, 6, 2, 2, CV_SHAPE_RECT, null);
        cvDilate(imgThreshold, imgThreshold, null, 3);

        cvSmooth(imgThreshold, imgThreshold, CV_MEDIAN, 5);
        return imgThreshold;


    }

    private IplImage getRGBSkin(IplImage orgImg) {
        IplImage imgHSV = cvCreateImage(cvGetSize(orgImg), 8, 3);
        IplImage imgThreshold = cvCreateImage(cvGetSize(orgImg), 8, 1);

        cvCvtColor(orgImg, imgHSV, CV_BGR2YCrCb);
        cvInRangeS(imgHSV, ycc_min, ycc_max, imgThreshold);
        //cvSmooth(imgThreshold, imgThreshold, CV_MEDIAN, 15);
        return imgThreshold;

    }

    private int[] extractContours(IplImage skin, IplImage img) {
        int[] yt=new int[2];
        double result1 = 0;
        double largest = 0;
        double secondlargest = 0;
        CvSeq largestcontour = new CvSeq(null);
        CvSeq secondlargestcontour = new CvSeq(null);
        CvSeq contours = new CvSeq(null);

        int a = cvFindContours(skin, storage, contours, Loader.sizeof(CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

        if (a != 0) {
            while (contours != null) {
                //   result1 = contours.total();
                result1 = cvContourArea(contours, CV_WHOLE_SEQ, 0);
                if (result1 > largest) {
//                secondlargest = largest;
                    largest = result1;
                    largestcontour = contours;
                }
//            if (secondlargest < result1 && largest != result1) {
//                secondlargest = result1;
//                secondlargestcontour = contours;
//            }
                contours = contours.h_next();
            }

            if (largestcontour != null) {

                cvDrawContours(img, largestcontour, CvScalar.MAGENTA, CvScalar.WHITE, -1, 1, CV_FLOODFILL_MASK_ONLY);

                hull = cvConvexHull2(largestcontour, storage, CV_COUNTER_CLOCKWISE, 1);
                largest = img.height() + 100;
                largest = img.width() + 100;
                //largest = 0;
                CvPoint v1 = null;
                for (int i = 0; i < hull.total(); i++) {

                    CvPoint v = new CvPoint(cvGetSeqElem(hull, i));

                    result1 = v.x();
                    if (result1 < largest) {
                        largest = result1;
                        v1 = v;
                    }
                }
                cvDrawCircle(img, v1, 5, CvScalar.RED, -1, 8, 0);
                System.out.println(" X value = " + v1.x() + " ; Y value =" + v1.y());
                yt[0]=v1.x();
                yt[1]=v1.y();
            }
            cvClearMemStorage(storage);
        }
        return yt;
    }
}


